// The following i-USE_UPfdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the BMTP_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// BMTP_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifndef __BMTP_H
#define __BMTP_H

#ifdef WIN32
    #ifdef BMTP_EXPORTS
        #define BMTP_API __declspec(dllexport)
    #else
        #define BMTP_API __declspec(dllimport)
    #endif
#else
    #define BMTP_API
#endif

// This class is exported from the BMTP.dll
//class BMTP_API CBMTP {
//public:
//	CBMTP(void);
//	// TODO: add your methods here.
//};

//extern BMTP_API int nBMTP;

//BMTP_API int fnBMTP(void);

/* 一切正常
 */
#define BMTP_OK                   0
/* 客户端内部错误
 * 客户端内存不足
 */
#define BMTP_OUT_OF_MEMORY        1
/* 客户端内部错误
 * 无法识别的消息头
 */
#define BMTP_UNRECOGNIZED_HEADER  8
/* 客户端内部错误
 * 未知状态
 */
#define BMTP_UNRECOGNIZED_STATE   9
/* 客户端内部错误
 * 未知错误
 */
#define BMTP_UNKNOWN_ERROR        5
/* 客户端内部错误
 * 流标识符不匹配
 */
#define BMTP_SID_UNMATCH          7

#define BMTP_SECURE_DISABLE  0
#define BMTP_SECURE_ENABLE   1

#define BMTP_AT_MOST_ONCE    0
#define BMTP_AT_LEAST_ONCE   1
#define BMTP_EXACTLY_ONCE    2

enum {
    TYPE_BOOL = 0,
    TYPE_VARINT,
    TYPE_64BIT,
    TYPE_STRING
};

enum {
    OP_RSV = 0,
    OP_CONN,
    OP_CONNACK,
    OP_PUB,
    OP_PUBACK,
    OP_SUB,
    OP_SUBACK,
    OP_PING,
    OP_PINGACK,
    OP_DISCONN,
    OP_WINDOW,
    OP_MAX
};

enum {
    RET_PUB_OK = 0,
    RET_PUB_SERVICE_UNAVAILABLE,
    RET_PUB_PERMISSION_DENIED,
    RET_PUB_INVALID_MESSAGE
};

enum {
    RET_SUB_OK = 0,
    RET_SUB_SERVICE_UNAVAILABLE,
    RET_SUB_PERMISSION_DENIED
};

enum {
    PARAM_CONN_AUTH = 1
};

enum {
    PARAM_PUB_STREAM_ID = 1,
    PARAM_PUB_MSG_ID,
    PARAM_PUB_TYPE,
    PARAM_PUB_PRODUCER_ID,
    PARAM_PUB_CONSUMER_ID,
    PARAM_PUB_CREATE,
    PARAM_PUB_EFFECT,
    PARAM_PUB_EXPIRE
};

enum {
    PARAM_SUB_CHANNEL_ID = 1
};

enum {
    PARAM_PUBACK_STREAM_ID = 1,
    PARAM_PUBACK_MSG_ID,
    PARAM_PUBACK_STATUS
};

enum {
    PARAM_SUBACK_CHANNEL_ID = 1,
    PARAM_SUBACK_STATUS
};

typedef void BMTP;
typedef void BMTP_PACKAGE;

typedef struct {
    unsigned long long int msg_id;
    unsigned long long int stream_id;
    unsigned long long int producer_id;
    unsigned long long int consumer_id;
    unsigned long long int create;
    unsigned long long int effect;
    unsigned long long int expire;
    unsigned int type:4;
    unsigned int is_compress:1;
    unsigned int is_lastwill:1;
    unsigned int data_len;
    const char *data;
} BMTP_MSG;

BMTP_API int bmtp_init();
BMTP_API void bmtp_cleanup();

BMTP_API BMTP* bmtp_new( const char *ip, int port, int secure );
BMTP_API int bmtp_reconnect( BMTP *p );

BMTP_API int bmtp_set_on_open( BMTP*, void( *on_open )( BMTP* ) );
BMTP_API int bmtp_set_on_close( BMTP*, void( *on_close )( BMTP* ) );
BMTP_API int bmtp_set_on_error( BMTP*, void( *on_error )( BMTP*, int err_no ) );
BMTP_API int bmtp_set_on_pub( BMTP*, void( *on_pub )( BMTP*, BMTP_MSG *msg ) );
BMTP_API int bmtp_set_on_ack( BMTP*, void( *on_ack )( BMTP*, BMTP_PACKAGE*, int status ) );

BMTP_API BMTP_PACKAGE* bmtp_package_new();
BMTP_API void bmtp_package_delete( BMTP_PACKAGE* );

BMTP_API int bmtp_package_add_param( BMTP_PACKAGE*, int key, int type, unsigned long long int l, const char *s );
BMTP_API int bmtp_package_set_opcode( BMTP_PACKAGE*, int op_code, int op_tyoe, unsigned long long int l);
BMTP_API int bmtp_package_set_payload( BMTP_PACKAGE*, unsigned int l, const char *s );

BMTP_API int bmtp_package_send( BMTP*, BMTP_PACKAGE* );

BMTP_API int bmtp_conn( BMTP*, const char *auth, int len );
BMTP_API int bmtp_sub( BMTP*, unsigned long long int channel_id );
BMTP_API int bmtp_pub( BMTP*, BMTP_MSG* );
BMTP_API int bmtp_ping( BMTP* );

BMTP_API int bmtp_debug( BMTP* );

#endif /* __BMTP_H */
